#include "msg_deal.h"
#include "../HAL/HAL.h"
#include "../public.h"

static struct rw_ctrl_handle
{
    uint8_t *txbuf;// 循环
    uint8_t *rxbuf;// 非循环
    uint16_t tx_rofs;
    uint16_t tx_wofs;
    uint16_t rx_rofs;
    uint16_t rx_wofs;
}* g_rw_handle = NULL;

uint8_t fingerprint[FINGER_LENTH];
static uint8_t get_usbd_reply = false;

void usbh_set_key_reply(uint8_t* data,uint16_t len)
{
    USB_LOG_RAW("usbd_set_key_reply\r\n");
}

void usbh_get_key_reply(uint8_t* data,uint16_t len)
{
    USB_LOG_RAW("usbd_get_key_reply+++++++++++\n");
    get_usbd_reply = true;
    memcpy(fingerprint,data,len);
    // if(pass == false)
    {
        FILE* fp = fopen("/sdcard/keys.txt","r");
        if(fp == NULL)
        {
            USB_LOG_RAW("file open err\n");
            return;
        }

        char line[512] = {0};
        while (fgets(line,512,fp) != NULL)
        {
            int len = strcspn(line,"\r\n");
            USB_LOG_RAW("len:%d\n",len);
            line[len] = 0;
            if (strcmp(line,(char*)fingerprint) == 0)
            {
                Asw3410_Set(1);
                // pass = true;
                break;
            }else
            {
                USB_LOG_RAW("%s,%s\n",line,fingerprint);
            }
            
        }
        fclose(fp);
    }
}


const cmd_msg_list usbh_msg_func_list[] = {
    {SET_KEY,       usbh_set_key_reply},
    {GET_KEY,       usbh_get_key_reply},
};

void usbh_recv_msg_deal(uint8_t* data,uint16_t len)
{
    for(int i = 0;i < sizeof(usbh_msg_func_list)/sizeof(cmd_msg_list);i++)
    {
        if(data[0] == usbh_msg_func_list[i].cmd)
        {
            usbh_msg_func_list[i].func(data+3,len-3);// cmd ll hh
            break;
        }
    }
}


// 0x77 0xAA 0x01 0x00 0x08 0x00 0x0C 0x36


static int match_usb_msg_head(uint8_t* recv_data,uint16_t recv_len,uint16_t* pkg_len,const uint8_t* head,uint8_t head_len)
{
    if(0 == memcmp(recv_data,head,head_len))
    {
        if(recv_len < 6)
        {
            *pkg_len =  USB_MSG_BUFF_SIZE;
        }else
        {
            *pkg_len = (recv_data[4]|recv_data[5]<<8);
        }
        return 1;
    }else
    {
        return 0;
    }
}

static int usb_msg_sum_check(uint8_t* packet_data,uint16_t len)
{
    uint8_t sum = 0;
    for(int i = 0; i < len-1; i++)
    {
        sum += packet_data[i];
    }
    if(sum == packet_data[len-1])
    {
        return 1;
    }
    return 0;
}


void usb_recv_process(void (func)(uint8_t*,uint16_t),const uint8_t* head,uint8_t head_len)
{
    uint16_t pkg_len;
    while (g_rw_handle->rx_wofs - g_rw_handle->rx_rofs > PACK_HEAD_LEN)
    {
        if(match_usb_msg_head(g_rw_handle->rxbuf+g_rw_handle->rx_rofs,(g_rw_handle->rx_wofs-g_rw_handle->rx_rofs),&pkg_len,head,head_len))
        {
            if(g_rw_handle->rx_wofs - g_rw_handle->rx_rofs >= pkg_len)
            {
                if(usb_msg_sum_check(g_rw_handle->rxbuf+g_rw_handle->rx_rofs,pkg_len))
                {
                    func(g_rw_handle->rxbuf+g_rw_handle->rx_rofs+head_len,pkg_len-head_len-1);
                    g_rw_handle->rx_rofs += pkg_len;
                }else
                {
                    g_rw_handle->rx_wofs = 0;
                    break;
                }
            }else
            {
                break;
            }
        }else
        {
            g_rw_handle->rx_wofs = 0;
            break;
        }
    }

    if(g_rw_handle->rx_rofs)
    {
        g_rw_handle->rx_wofs -= g_rw_handle->rx_rofs;
        if(g_rw_handle->rx_wofs)memcpy(g_rw_handle->rxbuf,(g_rw_handle->rxbuf+g_rw_handle->rx_rofs),g_rw_handle->rx_wofs);
        g_rw_handle->rx_rofs = 0;
    }
}

void usb_cache_recv_data(uint8_t* src,int len)
{
    memcpy(&g_rw_handle->rxbuf[g_rw_handle->rx_wofs],src,len);
    g_rw_handle->rx_wofs += len;
}

void usbh_connect_init()
{
    g_rw_handle = malloc(sizeof(struct rw_ctrl_handle));
    memset(g_rw_handle,0,sizeof(struct rw_ctrl_handle));
    g_rw_handle->rxbuf = usb_malloc(USB_MSG_BUFF_SIZE);
}
void usbh_disconnect_deinit()
{
    get_usbd_reply = false;
    memset(fingerprint,0,FINGER_LENTH);
    free(g_rw_handle->rxbuf);
    free(g_rw_handle);
    g_rw_handle = NULL;
}

uint8_t get_usbd_reply_state()
{
    return get_usbd_reply;
}